"""
wifi配置

@date:2018-1-31
@author:HXP

"""

import sys
import traceback

from PyQt5 import QtWidgets, uic
import serial
import array
import struct
import gzip
from UART import message_type
from UART.json_builder import AIUI
from UART.main_UART import COMThread

qtCreatorFile = "wifi.ui"  # Enter file here.

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)


class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        # 按钮监听
        self.confirm_button.clicked.connect(self.confirm_action)
        self.reset_button.clicked.connect(self.reset_action)
        self.check_button.clicked.connect(self.check_action)

        self.msg_ID = 0
        self.ser = serial.Serial(port='/dev/ttyUSB1', baudrate=115200, timeout=0.5)
        if self.ser is None:
            print('无法打开串口')

    def confirm_action(self):
        ssid = self.ssid_text.text()
        password = self.password_text.text()
        print('ssid:' + ssid)
        print('password:' + password)
        self.send_hand()
        # 串口操作
        try:
            flag_read = self.ser.read()  # 读取串口数据，一个字节
            if len(flag_read) > 0:  # 如果获取到数据
                flag_read += self.ser.read(6)  # 读到第六个字节，flag_read[0-6]
                if flag_read[0] == 165:  # 接收到数据 , flag is 0xA5 ,165（同步头）
                    data_len = COMThread.get_msg_len(flag_read)  # 接收到的数据长度
                    if 0 < data_len < 1024 * 1024:
                        data_read = self.ser.read(data_len)  # 读串口消息数据
                        self.ser.read()  # 读最后一个字节的校验码
                        self.send_ok(flag_read, message_type.OK_MSG)  # 向串口发送确认消息
                        self.send_wifi_conf(flag_read, ssid, password)  # 发送wifi配置信息
                        self.send_ok(flag_read, message_type.OK_MSG)
                        print('get one msg len=%d' % data_len)  # 打印消息长度
        except serial.SerialException:
            print('serial.SerialException ERROR')
            print(traceback.format_exc())

    def reset_action(self):
        self.ssid_text.clear()
        self.password_text.clear()

    def check_action(self):
        print('wifi status:')
        # 串口操作
        try:
            flag_read = self.ser.read()  # 读取串口数据，一个字节
            if len(flag_read) > 0:  # 如果获取到数据
                flag_read += self.ser.read(6)  # 读到第六个字节，flag_read[0-6]
                if flag_read[0] == 165:  # 接收到数据 , flag is 0xA5 ,165（同步头）
                    data_len = COMThread.get_msg_len(flag_read)  # 接收到的数据长度
                    if 0 < data_len < 1024 * 1024:
                        data_read = self.ser.read(data_len)  # 读串口消息数据
                        self.ser.read()  # 读最后一个字节的校验码
                        self.send_ok(flag_read, message_type.OK_MSG)  # 向串口发送确认消息
                        self.send_wifi_check(flag_read)  # 发送wifi状态查询信息
                        self.parse_msg(flag_read, data_read)  # 解析wifi状态信息
                        self.send_ok(flag_read, message_type.OK_MSG)
                        print('get one msg len=%d' % data_len)  # 打印消息长度
            flag_read = self.ser.read()  # 读取串口数据，一个字节
            if len(flag_read) > 0:  # 如果获取到数据
                flag_read += self.ser.read(6)  # 读到第六个字节，flag_read[0-6]
                if flag_read[0] == 165:  # 接收到数据 , flag is 0xA5 ,165（同步头）
                    data_len = COMThread.get_msg_len(flag_read)  # 接收到的数据长度
                    if 0 < data_len < 1024 * 1024:
                        data_read = self.ser.read(data_len)  # 读串口消息数据
                        self.ser.read()  # 读最后一个字节的校验码
                        self.send_ok(flag_read, message_type.OK_MSG)  # 向串口发送确认消息
                        self.parse_msg(flag_read, data_read)  # 解析wifi状态信息
                        self.send_ok(flag_read, message_type.OK_MSG)
                        print('get one msg len=%d' % data_len)  # 打印消息长度
        except serial.SerialException:
            print('serial.SerialException ERROR')
            print(traceback.format_exc())

    # 向串口发送wifi配置消息
    def send_wifi_conf(self, data, ssid, password):
        # 第0——2位
        send_data = array.array('B', [0xA5, 0x01, 0x02])
        # 第3——4位是消息长度
        msg_len = len(ssid) + len(password) + 4
        send_data.extend(struct.pack('<H', msg_len))
        # 第5——6位是消息ID
        send_data.extend(data[4:6])
        # 第7——m位是消息主题
        # 第7位是状态
        send_data.append(0x00)
        # 第8位是加密方式
        send_data.append(0x02)
        # 第9位是SSID长度
        send_data.extend(struct.pack('B', len(ssid)))
        # 第10位是passwd长度
        send_data.extend(struct.pack('B', len(password)))
        # 第11——m位是SSID
        for i in ssid:
            send_data.extend(i.encode('utf-8'))
        # 第m+1——n是passwd
        for i in password:
            send_data.extend(i.encode('utf-8'))
        # 第m+1位为校验位
        send_data.append((~sum(send_data) + 1) & 0xff)
        print(send_data)
        # 最后发送消息
        self.ser.write(send_data)

    # 查询wifi状态
    def send_wifi_check(self, data):
        # 第0——2位：同步头、用户ID、消息类型
        send_data = array.array('B', [0xA5, 0x01, message_type.CTRL_MSG])
        text = AIUI.wifi_status()
        text = '{"type": "status","content": {"query": "wifi"}}'
        msg = text.encode('utf-8')
        # 第3——4位是消息长度
        msg_len = len(msg)
        send_data.extend(struct.pack('<H', msg_len))
        # 第5——6位是消息ID
        send_data.extend(data[4:6])
        # 第7——m位是消息主题
        send_data.extend(msg)
        # 第m+1位为校验位
        send_data.append((~sum(send_data) + 1) & 0xff)
        print(send_data)
        # 最后发送消息
        self.ser.write(send_data)

    # 向串口发送确认消息
    def send_ok(self, data, msg_type):
        ok_msg = array.array('B', [0xA5, 0x01, msg_type, 0x04, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00, 0x00, 0x00])
        if data is None:
            self.msg_ID += 1
            if self.msg_ID > 65535:
                self.msg_ID = 0
            ok_msg[5] = self.msg_ID & 0xff
            ok_msg[6] = (self.msg_ID >> 8) & 0xff
        else:
            ok_msg[5] = (data[5])  # 设置消息ID
            ok_msg[6] = (data[6])
        ok_msg[11] = (~sum(ok_msg) + 1) & 0xff
        # print(ok_msg)
        self.ser.write(ok_msg)

    # 向串口发送握手消息
    def send_hand(self):
        hand_msg = array.array('B', [0xA5, 0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00, 0x00, 0x00])
        hand_msg[11] = (~sum(hand_msg) + 1) & 0xff
        # print(ok_msg)
        self.ser.write(hand_msg)


# 解析AIUI消息
def parse_msg(flag, data):
    print('msgType=%d' % (flag[2]))  # 打印出消息类型
    # 判断消息类型
    if flag[2] == message_type.AIUI_MSG:  # AIUI消息
        #           buf=StringIO(data)
        d = gzip.decompress(data)  # gzip解压
        json_data = d.decode('utf-8')  # utf-8解码
        print(json_data)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())
